import {extend, hasChanged, hasOwn, isArray, isIntegerKey, isObject} from "./utils.js";
import {readonly, reactive} from './reactive.js';
import {track, trigger} from './effects.js';
// readonly set时报错
// 是否是deep
const get = createGetter();
const shallowGet = createGetter(false, true);
const readonlyGet = createGetter(true, false);
const shallowReadonlyGet = createGetter(true, true);


const set = createSetter(false);
const shallowSet = createSetter(true)


function createGetter(isReadonly = false, shallow = false) {
  return function get(target, key, receiver) {
    // proxy reflect
    const res = Reflect.get(target, key, receiver);
    if (!isReadonly) {
      // 收集依赖，数据变化后更新视图
      // 取值的时候，会收集
      console.log('收集effect');
      track(target, 'get', key);
    }

    if (shallow) {
      return res;
    }
    if (isObject(res)) {
      return isReadonly ? readonly(res) : reactive(res)
    }
    return res;
  }
}

function createSetter(shallow = false) {
  return function set(target, key, value, receiver) {
    // 区分新增的，还是修改的
    const oldValue = target[key];

    let hadKey = isArray(target) && isIntegerKey(key) ? Number(key) < target.length : hasOwn(target, key);

    const result = Reflect.set(target, key, value, receiver);

    if (!hadKey) {
      // add
      trigger(target, 'add', key, value);
    } else if (hasChanged(oldValue, value)) {
      // modify
      trigger(target, 'set', key, value, value, oldValue);
    }

    return result;
  }
}


export const mutableHandlers = {
  get,
  set,
}
export const shallowReactiveHandlers = {
  get: shallowGet,
  set: shallowSet,
}
// extend Object.assign 合并
let readonlyObj = {
  set: (target, key) => {
    console.warn(`set ${target} to ${key} failed`);
  }
}
export const readonlyHandlers = extend({
  get: readonlyGet,
}, readonlyObj);

export const shallowReadonlyHandlers = extend({
  get: shallowReadonlyGet,
}, readonlyObj);
